#include <iostream>


template <class T>
class WinnerTree
{
public:
    virtual ~WinnerTree(){}
    /**
     * @brief initialize 根据传入的数据对私有变量进行初始化
     * @param thePlayer 选手指针
     * @param theNumberOfPlayers 选手个数
     */
    virtual void initialize(T* thePlayer, int theNumberOfPlayers) = 0;

    /**
     * @brief winner 获取赢者选手的索引
     * @return 选手的索引值
     */
    virtual int winner() const = 0;

    /**
     * @brief rePlay 当参赛者的分数发生变化的时候，重新比赛
     * @param thePlayer
     */
    virtual void rePlay(int thePlayer) = 0;
};

template <class T>
class CompleteWinnerTree :public WinnerTree<T>
{
public:
    CompleteWinnerTree(T* thePlayer, int theNumberOfPlayers){
        m_tree = nullptr;
        initialize(thePlayer, theNumberOfPlayers);
    }

    ~CompleteWinnerTree(){
        delete [] m_tree;
    }

    void initialize(T* thePlayer, int theNumberOfPlayers){
        if(theNumberOfPlayers <2){
            throw "Must have at least 2 players";
        }

        m_size = theNumberOfPlayers;
        m_player = thePlayer;

        m_tree = new int[m_size];

        int s(1);
        for(; 2 * s <= m_size - 1; s +=s); // s = 2^log (n-1)
        m_lowExt = 2 * (m_size - s);
        m_offset = 2 * s - 1;


    }

    int winner() const{return m_tree[1];}
    void rePlay(int thePlayer){}

private:
    T* m_player; // 直接引用外部指针，当外部选手修改的时候，可以直接重构竞赛树
    int* m_tree;
    int m_lowExt;
    int m_offset;
    int m_size;

};

int main(int argc, char *argv[])
{
  std::cout<<"Hello world."<<std::endl;
  return 0;
}
